package com.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Calendar;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.pagehelper.PageHelper;

import com.common.Page;
import com.common.Message;
import com.common.MD5Utils;
import com.common.ResultMessage;
import com.common.ServletWriteUtils;
import com.model.TestUser;
import com.service.TestUserService;
import org.springframework.web.util.WebUtils;

/**
 * 用户控制器
 *
 * Created by Administrator on 2018-7-23 0023.
 */
@Controller
@RequestMapping("/userManage")
public class UserController {

    private static final Logger log = LogManager.getLogger(UserController.class);

    @Resource
    private TestUserService testUserService;

    /**
     * 用户登录验证
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping("/userLogin")
    public ResultMessage userLogin(HttpServletRequest request) {

        ResultMessage resultMessage = new ResultMessage();
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        if (UserInfoCheck(resultMessage, username, password)) {
            return resultMessage;
        }

        try {
            TestUser testUser = getTestUserByName(username);
            //用户不存在
            if (testUser == null) {
                resultMessage.setCode(Message.USER_NOT_FIND.getCode());
                resultMessage.setMessage(Message.USER_NOT_FIND.getDesc());
                return resultMessage;
            } else {
                String md5Password = testUser.getMd5Password();
                //用户存在，并且登录成功
                if (StringUtils.isNoneBlank(md5Password) && StringUtils.equals(MD5Utils.executeMD5(password), md5Password)) {
                    HttpSession session = request.getSession();
                    session.setAttribute(Message.LOGIN_SUCCESS_SESSION.getCode(), testUser);
                    resultMessage.setCode(Message.LOGIN_SUCCESS.getCode());
                    resultMessage.setMessage(Message.LOGIN_SUCCESS.getDesc());
                } else {
                    // 密码不匹配
                    resultMessage.setCode(Message.PASSWORD_MISMATCH.getCode());
                    resultMessage.setMessage(Message.PASSWORD_MISMATCH.getDesc());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("userLogin 异常", e.getMessage());
            resultMessage.setCode(Message.SYSTEM_EXCEPTION.getCode());
            resultMessage.setMessage(Message.SYSTEM_EXCEPTION.getDesc());
        }
        return resultMessage;
    }


    private boolean UserInfoCheck(ResultMessage resultMessage, String username, String password) {
        if (StringUtils.isBlank(username)) {
            resultMessage.setCode(Message.USERNAME_IS_NULL.getCode());
            resultMessage.setMessage(Message.USERNAME_IS_NULL.getDesc());
            return true;
        }
        if (StringUtils.isBlank(password)) {
            resultMessage.setCode(Message.PASSWORD_IS_NULL.getCode());
            resultMessage.setMessage(Message.PASSWORD_IS_NULL.getDesc());
            return true;
        }
        return false;
    }

    /**
     * 用户新增
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping("/userAdd")
    private ResultMessage userAdd(HttpServletRequest request) {
        ResultMessage resultMessage = new ResultMessage();
        try {
            String userdata = WebUtils.findParameterValue(request, "userdata");
            TestUser testUser = JSON.parseObject(userdata, new TypeReference<TestUser>(){});
            TestUser testUserByName = null;
            if(testUser != null && StringUtils.isNotBlank(testUser.getUserName())){
                testUserByName = testUserService.getUserByName(testUser.getUserName());
            }
            if (testUserByName != null) {
                resultMessage.setCode(Message.USER_FIND.getCode());
                resultMessage.setMessage(Message.USER_FIND.getDesc());
                return resultMessage;
            } else {
                TestUser user = new TestUser();
                Calendar calendar = Calendar.getInstance();
                user.setId(calendar.get(Calendar.MILLISECOND));
                user.setUserName(testUser.getUserName());
                user.setRealName("test" + testUser.getUserName());
                user.setPassword(testUser.getPassword());
                user.setMd5Password(MD5Utils.executeMD5(testUser.getPassword()));
                Integer result = testUserService.insertTestUser(user);

                if (result > 0) {
                    resultMessage.setCode(Message.ADD_USER_SUCCESS.getCode());
                    resultMessage.setMessage(Message.ADD_USER_SUCCESS.getDesc());
                } else {
                    resultMessage.setCode(Message.ADD_USER_FAILED.getCode());
                    resultMessage.setMessage(Message.ADD_USER_FAILED.getDesc());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("testUserService.insertTestUser 异常", e.getMessage());
            resultMessage.setCode(Message.SYSTEM_EXCEPTION.getCode());
            resultMessage.setMessage(Message.SYSTEM_EXCEPTION.getDesc());
        }
        return resultMessage;
    }


    private TestUser getTestUserByName(String username) throws Exception {
        return testUserService.getUserByName(username);
    }


    @ResponseBody
    @RequestMapping("/getUserList")
    private TestUser getTestUserListById() {
        log.info("根据id查询用户");
        TestUser user = null;
        Integer userId = 1;
        try {
            user = testUserService.getTestUserById(userId);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("testUserService.getTestUserById 异常", e.getMessage());
        }
        return user;
    }

    @ResponseBody
    @RequestMapping("/getAllList")
    private List<Object> getAllList(HttpServletRequest request) {
        log.info("查询所有用户");
        List<Object> list = Lists.newArrayList();
        try {
            if (checkUserLogin(request, list)) {
                return list;
            }
            list.addAll(testUserService.getAllList());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("testUserService.getAllList 异常", e.getMessage());
        }
        return list;
    }


    /**
     * FastJSON过滤指定的属性字段
     *
     * @param response
     */
    @RequestMapping("/getAllUserByJSONExclude")
    private void getAllUserByJSONExclude(HttpServletResponse response) {
        try {
            List<TestUser> list = testUserService.getAllList();
            String str = "";
            List<String> excludeList = Lists.newArrayList("password", "userName", "email", "realName");
            if (list != null && !list.isEmpty()) {
                SimplePropertyPreFilter simplePropertyPreFilter = null;
                for (TestUser user : list) {
                    simplePropertyPreFilter = new SimplePropertyPreFilter();
                    simplePropertyPreFilter.getExcludes().addAll(excludeList);
                }
                str = JSON.toJSONString(list, simplePropertyPreFilter);
            }
            ServletWriteUtils.responseString(response, str);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("testUserService.getAllUserByJSONExclude 异常", e.getMessage());
        }
    }


    /**
     * FastJSON只序列化包含的属性字段
     *
     * @param response
     */
    @RequestMapping("/getAllUserByJSONInclude")
    private void getAllUserByJSONInclude(HttpServletResponse response) throws IOException {
        try {
            ResultMessage message = new ResultMessage();

            List<TestUser> list = testUserService.getAllList();
            // json序列化包含的字段，该字段跟TestUser字段名字一致
            String[] include = {"id", "userName", "realName", "email"};
            if (list != null && !list.isEmpty()) {
                SimplePropertyPreFilter simplePropertyPreFilter = null;
                for (TestUser user : list) {
                    simplePropertyPreFilter = new SimplePropertyPreFilter(TestUser.class, include);
                }
                String strJson = JSON.toJSONString(list, simplePropertyPreFilter);
                message.setCode(Message.USER_DATA_SEARCH_SUCCESS.getCode());
                message.setMessage(Message.USER_DATA_SEARCH_SUCCESS.getDesc());
                message.setDataObject(strJson);
                ServletWriteUtils.responseString(response, JSON.toJSONString(message));
            } else {
                message.setCode(Message.USER_DATA_SEARCH_FAILED.getCode());
                message.setMessage(Message.USER_DATA_SEARCH_FAILED.getDesc());
                ServletWriteUtils.responseString(response, message.toString());
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("testUserService.getAllUserByJSONInclude 异常", e.getMessage());
            ResultMessage exceptionMsg = new ResultMessage();
            exceptionMsg.setCode(Message.SYSTEM_EXCEPTION.getCode());
            exceptionMsg.setMessage(Message.SYSTEM_EXCEPTION.getDesc());
            ServletWriteUtils.responseJSONString(response, exceptionMsg);
        }
    }

    /**
     * 是否有已经登录的用户
     *
     * @param request
     * @param list
     * @return
     */
    private boolean checkUserLogin(HttpServletRequest request, List<Object> list) throws Exception {
        TestUser user = (TestUser) request.getSession().getAttribute(Message.LOGIN_SUCCESS_SESSION.getCode());
        if (user == null) {
            ResultMessage resultMessage = new ResultMessage();
            resultMessage.setCode(Message.NO_USER_LOGIN.getCode());
            resultMessage.setMessage(Message.NO_USER_LOGIN.getDesc());
            list.add(resultMessage);
            return true;
        }
        return false;
    }

    @ResponseBody
    @RequestMapping("/getAllForPage")
    private Map<String, Object> getAllForPage(HttpServletRequest request) {
        log.info("分页查询用户");
        Map<String, Object> map = Maps.newHashMap();
        try {
            Integer currentPage = Integer.parseInt(request.getParameter("currentPage"));
            Integer pageSize = Integer.parseInt(request.getParameter("pageSize"));
            int totalCount = testUserService.selectCount();
            PageHelper.startPage(currentPage, pageSize);
            Page page = new Page(currentPage, pageSize, totalCount);
            List<TestUser> list = testUserService.getAllList();
            page.setPageList(list);
            if (currentPage > page.getTotalPages()) {
                String msg = "总共只有" + page.getTotalPages() + "页，不要再翻下一页了";
                map.put("data", msg);
            } else {
                map.put("data", page);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("getAllForPage error", e.getMessage());
            map.put("data", e.getMessage());
        }
        return map;
    }

    @ResponseBody
    @RequestMapping("/delById")
    public ResultMessage userDeleteById(HttpServletRequest request) {
        ResultMessage message = new ResultMessage();
        String id = request.getParameter("userId");
        if(StringUtils.isBlank(id)){
            message.setCode(Message.USER_ID_IS_NULL.getCode());
            message.setMessage(Message.USER_ID_IS_NULL.getDesc());
            return message;
        } else {
            int count = 0;
            try {
                count = testUserService.deleteById(Integer.parseInt(id));
            } catch (Exception e) {
                e.printStackTrace();
                log.error("userDelById 异常", e.getMessage());
                message.setCode(Message.SYSTEM_EXCEPTION.getCode());
                message.setMessage(Message.SYSTEM_EXCEPTION.getDesc());
            }
            if (count <= 0) {
                message.setCode(Message.DEL_USER_FAILED.getCode());
                message.setMessage(Message.DEL_USER_FAILED.getDesc());
            } else {
                message.setCode(Message.DEL_USER_SUCCESS.getCode());
                message.setMessage(Message.DEL_USER_SUCCESS.getDesc());
            }
            return message;
        }
    }


    @ResponseBody
    @RequestMapping("/updateById")
    public ResultMessage userUpdateById(HttpServletRequest request){
        ResultMessage message = new ResultMessage();
        String data = request.getParameter("userData");
        if(StringUtils.isBlank(data)){
            message.setCode(Message.USER_ID_IS_NULL.getCode());
            message.setMessage(Message.USER_ID_IS_NULL.getDesc());
            return message;
        } else {
            int count = 0;
            try {
                TestUser user = JSON.parseObject(data, new TypeReference<TestUser>(){});
                count = testUserService.updateTestUser(user);
            } catch (Exception e) {
                e.printStackTrace();
                log.error("userUpdateById 异常", e.getMessage());
                message.setCode(Message.SYSTEM_EXCEPTION.getCode());
                message.setMessage(Message.SYSTEM_EXCEPTION.getDesc());
            }
            if(count <= 0){
                message.setCode(Message.UPDATE_USER_FAILED.getCode());
                message.setCode(Message.UPDATE_USER_FAILED.getDesc());
            } else {
                message.setCode(Message.UPDATE_USER_SUCCESS.getCode());
                message.setMessage(Message.UPDATE_USER_SUCCESS.getDesc());
            }
            return message;
        }
    }


}
